home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
apps
/
93
/
applic
/
sdbscn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-01-15
|
14KB
|
627 lines
/* SDB - token scanning routines */
#include "sdbio.h"
int dbv_token; /* current token */
int dbv_tvalue; /* integer token value */
char dbv_tstring[STRINGMAX+1]; /* string token value */
struct ifile *dbv_ifp; /* indirect file context */
struct macro *dbv_macros; /* macro definitions */
int dbv_fold; /* case fold alpha comparisons */
static char *iprompt,*cprompt; /* input prompts */
static char cmdline[LINEMAX+2],*lptr; /* current line and pointer */
static int atbol; /* flag indicating at bol */
static int savech; /* lookahead character */
static int savetkn; /* lookahead token */
static char *keywords[] = { /* keyword table */
"ascending",
"by",
"char",
"compress",
"create",
"define",
"delete",
"descending",
"exit",
"export",
"extract",
"from",
"help",
"insert",
"import",
"into",
"num",
"print",
"select",
"set",
"show",
"sort",
"update",
"using",
"where",
NULL
};
static int keytokens[] = { /* token values for each keyword */
ASCENDING,
BY,
CHAR,
COMPRESS,
CREATE,
DEFINE,
DELETE,
DESCENDING,
EXIT,
EXPORT,
EXTRACT,
FROM,
HELP,
INSERT,
IMPORT,
INTO,
NUM,
PRINT,
SELECT,
SET,
SHOW,
SORT,
UPDATE,
USING,
WHERE,
NULL
};
/* db_sinit - initialize the scanner */
db_sinit()
{
/* at beginning of line */
atbol = TRUE;
/* make the command line null */
lptr = NULL;
/* no lookahead yet */
savech = EOS;
savetkn = 0;
/* no indirect command files */
dbv_ifp = NULL;
/* no macros defined */
dbv_macros = NULL;
/* fold alpha comparisons */
dbv_fold = TRUE;
}
/* db_prompt(ip,cp) - initialize prompt strings */
db_prompt(ip,cp)
char *ip,*cp;
{
/* save initial and continuation prompt strings */
iprompt = ip;
cprompt = cp;
}
/* db_scan(fmt,args) - initiate line scan command parsing */
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
{
/* convert the command line and arguments */
sprintf(cmdline,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
/* start at the beginning of the command line */
lptr = cmdline;
iprompt = NULL;
dbv_ifp = NULL;
/* no lookahead yet */
savech = EOS;
savetkn = 0;
/* fold alpha comparisons */
dbv_fold = TRUE;
}
/* db_flush - flush the current input line */
int db_flush()
{
while (savech != '\n')
if (savech > ' ')
return (db_ferror(SYNTAX));
else
savech = getchx();
savech = EOS;
atbol = TRUE;
return (TRUE);
}
/* db_gline - get a line from the current input */
char *db_gline(buf)
char *buf;
{
int ch,i;
for (i = 0; (ch = getch()) != '\n' && ch != -1; )
if (i < LINEMAX)
buf[i++] = ch;
else {
printf("*** line too long ***\nRetype> ");
i = 0;
}
buf[i] = EOS;
return (buf);
}
/* db_ifile - setup an indirect command file */
int db_ifile(fname)
char *fname;
{
struct ifile *new_ifp;
if ((new_ifp = (struct ifile *)malloc(sizeof(struct ifile))) == NULL)
return (db_ferror(INSMEM));
else if ((new_ifp->if_fp = fopen(fname,"r")) == NULL) {
free(new_ifp);
return (db_ferror(INDFNF));
}
new_ifp->if_mtext = NULL;
new_ifp->if_savech = savech;
new_ifp->if_lptr = lptr;
new_ifp->if_next = dbv_ifp;
dbv_ifp = new_ifp;
/* return successfully */
return (TRUE);
}
/* db_kill - kill indirect command file input */
db_kill()
{
struct ifile *old_ifp;
while ((old_ifp = dbv_ifp) != NULL) {
dbv_ifp = old_ifp->if_next;
if (old_ifp->if_fp != NULL)
fclose(old_ifp->if_fp);
savech = old_ifp->if_savech;
lptr = old_ifp->if_lptr;
free(old_ifp);
}
while (savech != '\n')
savech = getchx();
savech = EOS;
savetkn = 0;
atbol = TRUE;
}
/* db_token - return the current input token */
int db_token()
{
struct macro *mptr;
struct ifile *new_ifp;
/* find a token that's not a macro call */
while (db_xtoken() == ID) {
/* check for a macro call */
for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next)
if (db_scmp(dbv_tstring,mptr->mc_name) == 0) {
if ((new_ifp = (struct ifile *)malloc(sizeof(struct ifile))) == NULL)
printf("*** error expanding macro: %s ***\n",dbv_tstring);
else {
new_ifp->if_fp = NULL;
new_ifp->if_mtext = mptr->mc_mtext->mt_next;
new_ifp->if_lptr = lptr; lptr = mptr->mc_mtext->mt_text;
new_ifp->if_savech = savech; savech = EOS;
new_ifp->if_next = dbv_ifp;
dbv_ifp = new_ifp;
}
savetkn = 0;
break;
}
if (mptr == NULL)
break;
}
return (dbv_token);
}
/* db_xtoken - return the current input token */
int db_xtoken()
{
int ch;
/* check for a saved token */
if ((dbv_token = savetkn) != 0)
return (dbv_token);
/* get the next non-blank character */
ch = nextch();
/* check type of character */
if (isalpha(ch)) /* identifier or keyword */
get_id();
else if (isdigit(ch)) /* number */
get_number();
else if (ch == '"') /* string */
get_string();
else if (get_rel()) /* relational operator */
;
else /* single character token */
dbv_token = getch();
/* save the lookahead token */
savetkn = dbv_token;
/* return the token */
return (dbv_token);
}
/* db_ntoken - get next token (after skipping the current one) */
int db_ntoken()
{
/* get the current token */
db_token();
/* make sure another is read on next call */
savetkn = 0;
/* return the current token */
return (dbv_token);
}
/* db_xntoken - get next token (after skipping the current one) */
int db_xntoken()
{
/* get the current token */
db_xtoken();
/* make sure another is read on next call */
savetkn = 0;
/* return the current token */
return (dbv_token);
}
/* db_scmp - compare two strings */
int db_scmp(str1,str2)
char *str1,*str2;
{
if (dbv_fold)
return (scmp(str1,str2));
else
return (strcmp(str1,str2));
}
/* db_sncmp - compare two strings with a maximum length */
int db_sncmp(str1,str2,len)
char *str1,*str2; int len;
{
if (dbv_fold)
return (sncmp(str1,str2,len));
else
return (strncmp(str1,str2,len));
}
/* scmp - compare two strings with alpha case folding */
static int scmp(str1,str2)
char *str1,*str2;
{
int ch1,ch2;
/* compare each character */
while (*str1 && *str2) {
/* fold the character from the first string */
if (isupper(*str1))
ch1 = tolower(*str1++);
else
ch1 = *str1++;
/* fold the character from the second string */
if (isupper(*str2))
ch2 = tolower(*str2++);
else
ch2 = *str2++;
/* compare the characters */
if (ch1 != ch2)
if (ch1 < ch2)
return (-1);
else
return (1);
}
/* check for strings of different lengths */
if (*str1 == *str2)
return (0);
else if (*str1 == 0)
return (-1);
else
return (1);
}
/* sncmp - compare two strings with alpha case folding and a maximum length */
static int sncmp(str1,str2,len)
char *str1,*str2; int len;
{
int ch1,ch2;
/* compare each character */
while (*str1 && *str2 && len > 0) {
/* fold the character from the first string */
if (isupper(*str1))
ch1 = tolower(*str1++);
else
ch1 = *str1++;
/* fold the character from the second string */
if (isupper(*str2))
ch2 = tolower(*str2++);
else
ch2 = *str2++;
/* compare the characters */
if (ch1 != ch2)
if (ch1 < ch2)
return (-1);
else
return (1);
/* decrement the string length */
len--;
}
/* check for strings of different lengths */
if (len == 0 || *str1 == *str2)
return (0);
else if (*str1 == 0)
return (-1);
else
return (1);
}
/* get_id - get a keyword or a user identifier */
static get_id()
{
int ch,nchars,i;
/* input letters and digits */
ch = nextch();
nchars = 0;
while (isalpha(ch) || isdigit(ch)) {
if (nchars < KEYWORDMAX)
dbv_tstring[nchars++] = ch;
getch(); ch = thisch();
}
/* terminate the keyword */
dbv_tstring[nchars] = EOS;
/* assume its an identifier */
dbv_token = ID;
/* check for keywords */
for (i = 0; keywords[i] != NULL; i++)
if (db_scmp(dbv_tstring,keywords[i]) == 0)
dbv_token = keytokens[i];
}
/* get_number - get a number */
static get_number()
{
int ch,ndigits,nodot;
/* read digits and at most one decimal point */
ch = nextch();
ndigits = 0; nodot = TRUE;
while (isdigit(ch) || (nodot && ch == '.')) {
if (ch == '.')
nodot = FALSE;
if (ndigits < NUMBERMAX)
dbv_tstring[ndigits++] = ch;
getch(); ch = thisch();
}
/* terminate the number */
dbv_tstring[ndigits] = EOS;
/* get the value of the number */
sscanf(dbv_tstring,"%d",&dbv_tvalue);
/* token is a number */
dbv_token = NUMBER;
}
/* get_string - get a string */
static get_string()
{
int ch,nchars;
/* skip the opening quote */
getch();
/* read characters until a closing quote is found */
ch = thisch();
nchars = 0;
while (ch && ch != '"') {
if (nchars < STRINGMAX)
dbv_tstring[nchars++] = ch;
getch(); ch = thisch();
}
/* terminate the string */
dbv_tstring[nchars] = EOS;
/* skip the closing quote */
getch();
/* token is a string */
dbv_token = STRING;
}
/* get_rel - get a relational operator */
static int get_rel()
{
int ch;
switch (ch = nextch()) {
case '=':
getch();
dbv_token = EQL;
return (TRUE);;
case '<':
getch(); ch = nextch();
if (ch == '>') {
getch();
dbv_token = NEQ;
}
else if (ch == '=') {
getch();
dbv_token = LEQ;
}
else
dbv_token = LSS;
return (TRUE);;
case '>':
getch(); ch = nextch();
if (ch == '=') {
getch();
dbv_token = GEQ;
}
else
dbv_token = GTR;
return (TRUE);;
default:
return (FALSE);
}
}
/* getch - get the next character */
static int getch()
{
char fname[STRINGMAX+1];
int ch,i;
/* return the lookahead character if there is one */
if (savech != EOS) {
ch = savech;
savech = EOS;
return (ch);
}
/* get a character */
ch = getchx();
/* skip spaces at the beginning of a command */
if (atbol && iprompt != NULL)
while (ch <= ' ')
ch = getchx();
/* use continuation prompt next time */
iprompt = NULL;
/* check for indirect command file */
while (ch == '@') {
for (i = 0; (savech = getchx()) > ' '; )
if (i < STRINGMAX)
fname[i++] = savech;
fname[i] = 0;
if (db_ifile(fname) != TRUE)
printf("*** error opening command file: %s ***\n",fname);
ch = getchx();
}
/* return the character */
return (ch);
}
/* getchx - get the next character */
static int getchx()
{
struct ifile *old_ifp;
int ch;
/* check for input from buffer */
if (lptr != NULL) {
while (*lptr == EOS)
if (dbv_ifp != NULL)
if (dbv_ifp->if_mtext == NULL) {
old_ifp = dbv_ifp;
ch = dbv_ifp->if_savech; savech = EOS;
lptr = dbv_ifp->if_lptr;
dbv_ifp = dbv_ifp->if_next;
free(old_ifp);
if (ch != EOS)
return (ch);
if (lptr == NULL)
break;
}
else {
lptr = dbv_ifp->if_mtext->mt_text;
dbv_ifp->if_mtext = dbv_ifp->if_mtext->mt_next;
}
else
return (EOS);
if (lptr != NULL)
return (*lptr++);
}
/* print prompt if necessary */
if (atbol && dbv_ifp == NULL)
if (iprompt != NULL)
printf("%s",iprompt);
else if (cprompt != NULL)
printf("%s",cprompt);
if (dbv_ifp == NULL)
if ((ch = getc(stdin)) == '\n')
atbol = TRUE;
else
atbol = FALSE;
else {
if ((ch = getc(dbv_ifp->if_fp)) == -1) {
old_ifp = dbv_ifp;
ch = dbv_ifp->if_savech; savech = EOS;
lptr = dbv_ifp->if_lptr;
dbv_ifp = dbv_ifp->if_next;
fclose(old_ifp->if_fp);
free(old_ifp);
}
}
/* return the character */
return (ch);
}
/* thisch - get the current character */
static int thisch()
{
/* get a lookahead character */
if (savech == EOS)
savech = getch();
/* return lookahead character */
return (savech);
}
/* nextch - get the next non-blank character */
static int nextch()
{
int ch;
/* skip blank characters */
while ((ch = thisch()) <= ' ' && ch != EOS)
getch();
/* return the first non-blank */
return (ch);
}